<template>
    <div style="padding: 10px;">
        <div style="width: 450px;">
            <Tree :ref="treeRefName" :data="treeData" :render="renderContent" :show-checkbox="showCheckbox" multiple check-strictly></Tree>
        
            <div style="text-align: center;">
                <Button type="primary" @click="handleRolePermissionSubmit" v-if="showCheckbox" long>保存角色权限设置</Button>
            </div>
        </div>

        <div>
            <Modal
                    v-model="editAndCreateModal.show"
                    :title="editAndCreateModal.title"
                    footer-hide
                    @on-cancel="editAndCreateModal.show = false"
            >
                <Form v-if="editAndCreateModal.show" :ref="editAndCreateModal.formRef" :model="editAndCreateModal.data" :label-width="120">
                    <FormItem label="名称" prop="title" required>
                        <Input type="text" v-model="editAndCreateModal.data.title" placeholder="名称"></Input>
                    </FormItem>

                    <FormItem label="api" prop="api_uri" v-if="editAndCreateModal.data.level === 3">
                        <Input type="text" v-model="editAndCreateModal.data.api_uri" placeholder="uri地址，e.g, laravel 路由 /user/{id}/post, 正则：/^\/user\/\d+$/"></Input>
                    </FormItem>

                    <FormItem label="api请求方式" prop="api_method" v-if="editAndCreateModal.data.level === 3">
                        <Select v-model="editAndCreateModal.data.api_method" size="small" style="width:100px">
                            <Option v-for="item in editAndCreateModal.apiMethodList" :value="item.value" :key="item.value">{{ item.label }}</Option>
                        </Select>
                    </FormItem>
    
                    <FormItem label="api匹配类型" prop="status" v-if="editAndCreateModal.data.level === 3">
                        <RadioGroup v-model="editAndCreateModal.data.api_match_type">
                            <Radio :label="0">
                                <Icon type="social-apple"></Icon>
                                <span>laravel路由</span>
                            </Radio>
                            <Radio :label="1">
                                <Icon type="social-android"></Icon>
                                <span>绝对匹配</span>
                            </Radio>
                            <Radio :label="2">
                                <Icon type="social-android"></Icon>
                                <span>正则匹配</span>
                            </Radio>
                        </RadioGroup>
                    </FormItem>

                    <FormItem label="路由name属性" prop="route_name" v-if="editAndCreateModal.data.level !== 3" required>
                        <Input type="text" v-model.trim="editAndCreateModal.data.route_name" placeholder="vue的路由中的name属性"></Input>
                    </FormItem>

                    <FormItem label="描述" prop="desc">
                        <Input type="text" v-model="editAndCreateModal.data.desc"></Input>
                    </FormItem>

                    <FormItem label="路由icon" prop="meta_icon" v-if="editAndCreateModal.data.level !== 3">
                        <Input type="text" v-model="editAndCreateModal.data.meta_icon"></Input>
                    </FormItem>

                    <FormItem label="状态" prop="status">
                        <i-switch v-model="editAndCreateModal.data.status" :true-value="1" :false-value="0" size="large">
                            <span slot="open">启用</span>
                            <span slot="close">不启用</span>
                        </i-switch>
                    </FormItem>

                    <FormItem label="是否隐藏tab面包屑" prop="meta_hide_in_bread" v-if="editAndCreateModal.data.level === 2">
                        <i-switch v-model="editAndCreateModal.data.meta_hide_in_bread" :true-value="1" :false-value="0" size="large">
                            <span slot="open">是</span>
                            <span slot="close">否</span>
                        </i-switch>
                    </FormItem>

                    <!--目录这个一定为1-->
                    <FormItem label="是否在导航中隐藏" prop="meta_hide_in_menu" v-if="editAndCreateModal.data.level !== 3">
                        <i-switch v-model="editAndCreateModal.data.meta_hide_in_menu" :true-value="1" :false-value="0" size="large">
                            <span slot="open">是</span>
                            <span slot="close">否</span>
                        </i-switch>
                    </FormItem>

                    <FormItem label="是否不使用缓存" prop="meta_not_cache" v-if="editAndCreateModal.data.level === 2">
                        <i-switch v-model="editAndCreateModal.data.meta_not_cache" :true-value="1" :false-value="0" size="large">
                            <span slot="open">是</span>
                            <span slot="close">否</span>
                        </i-switch>
                    </FormItem>

                    <FormItem label="是否显示目录伸展" prop="meta_show_always" v-if="editAndCreateModal.data.level === 1">
                        <i-switch v-model="editAndCreateModal.data.meta_show_always" :true-value="1" :false-value="0" size="large">
                            <span slot="open">是</span>
                            <span slot="close">否</span>
                        </i-switch>
                        tip:这里如果目录下没有子节点设为“否”，否则会有问题
                    </FormItem>

                    <FormItem label="路由meta.access属性" prop="meta_access" v-if="editAndCreateModal.data.level === 2">
                        <Input type="text" v-model="editAndCreateModal.data.meta_access"></Input>
                    </FormItem>

                    <FormItem label="路由meta.beforeCloseName属性" prop="meta_before_close_name" v-if="editAndCreateModal.data.level === 2">
                        <Input type="text" v-model="editAndCreateModal.data.meta_before_close_name"></Input>
                    </FormItem>

                    <FormItem label="路由meta.pinyin属性" prop="meta_pinyin" v-if="editAndCreateModal.data.level === 2">
                        <Input type="text" v-model="editAndCreateModal.data.meta_pinyin"></Input>
                    </FormItem>

                    <FormItem label="路由props属性" prop="props" v-if="editAndCreateModal.data.level !== 3">
                        <Card>
                            <Button type="dashed" @click="handleEditAndCreateModalFormPropsAdd" icon="md-add" size="small">添加路由props属性配置</Button>
        
                            <Row v-for="(item, index) in editAndCreateModal.propsList">
                                <Input style="width: 80px" type="text" v-model="item.key" placeholder="Enter Key" size="small"></Input>
                                <Input style="width: 80px; margin-left: 10px" type="text" v-model="item.value" placeholder="Enter Value" size="small"></Input>
                                <Button style="margin-left: 10px" @click="handleEditAndCreateModalFormPropsRemove(index)" size="small">删除</Button>
                            </Row>
                        </Card>
                    </FormItem>

                    <FormItem label="拓展信息" prop="ext">
                        <Input type="text" v-model="editAndCreateModal.data.ext" placeholder="拓展信息"></Input>
                    </FormItem>

                    <FormItem label="排序" prop="order">
                        <Slider v-model="editAndCreateModal.data.order"></Slider>
                    </FormItem>

                    <FormItem>
                        <Button type="primary" @click="handleEditAndCreateSubmit">提交</Button>
                    </FormItem>

                </Form>
            </Modal>
        </div>
    </div>
</template>

<script>
    import rbacUtl from '../auth-route-utl'
    const defaultFormData = {
        title: '',
        level: 1,
        pid  : 0,

        api_uri       : '',
        api_method    : '',
        api_match_type: 0,

        ext       : '',
        desc      : '',
        status    : 1,
        order     : 1,
        route_name: '',
        props     : {},

        meta_hide_in_bread    : 0,
        meta_hide_in_menu     : 0,
        meta_not_cache        : 1,
        meta_show_always      : 0,// 这里如果目录下没有子节点设为true，会有问题
        meta_access           : '',
        meta_icon             : '',
        meta_before_close_name: '',
        meta_pinyin           : ''
    };
    export default {
        name   : "rbacPowerPage",
        props : {
            permissionCheckIdList: {
                type   : Array,
                default: () => []
            },
            showCheckbox         : {
                type   : Boolean,
                default: false,
            },
            showOpBtn            : {
                type   : Boolean,
                default: true,
            },
        },
        data() {
            return {
                treeRefName       : 'treeRef',
                editAndCreateModal: {
                    show                : false,
                    title               : '',
                    data                : Object.assign({},defaultFormData),
                    levelCreateTitleInfo: {
                        0: '目录',
                        1: '页面',
                        2: 'api'
                    },
                    propsList           : [],
                    formRef             : 'createAndEditForm',
                    apiMethodList:[
                        {
                            value: 'POST',
                            label: 'POST'
                        },
                        {
                            value: 'PUT',
                            label: 'PUT'
                        },
                        {
                            value: 'DELETE',
                            label: 'DELETE'
                        },
                        {
                            value: 'GET',
                            label: 'GET'
                        },
                        {
                            value: 'PATCH',
                            label: 'PATCH'
                        },
                        {
                            value: 'OPTIONS',
                            label: 'OPTIONS'
                        },
                        {
                            value: 'HEAD',
                            label: 'HEAD'
                        },
                        {
                            value: 'CONNECT',
                            label: 'CONNECT'
                        },
                        {
                            value: 'TRACE',
                            label: 'TRACE'
                        }
                    ]
                },
                treeData          : [
                    {
                        title   : '所有',
                        expand  : true,
                        render  : (h, {root, node, data}) => {
                            return h('span', {
                                style: {
                                    display: 'inline-block',
                                    width  : '100%'
                                }
                            }, [
                                h('span', [
                                    h('Icon', {
                                        props: {
                                            type: 'ios-folder-outline'
                                        },
                                        style: {
                                            marginRight: '8px'
                                        }
                                    }),
                                    h('span', data.title)
                                ]),
                                h('span', {
                                    style: {
                                        display    : 'inline-block',
                                        float      : 'right',
                                        marginRight: '32px'
                                    }
                                }, [
                                    h('Button', {
                                        props: Object.assign({}, this.buttonProps, {
                                            icon: 'md-cloud-download',
                                            type: 'primary'
                                        }),
                                        style: {
                                            width: '64px'
                                        },
                                        on   : {
                                            click: () => { this.append(data) }
                                        }
                                    })
                                ])
                            ]);
                        },
                        children: [],
                    }
                ],
                buttonProps       : {
                    type: 'default',
                    size: 'small'
                },
                treeIconMap: {//根据目录\页面\api的level来设置不同的展示ico
                    1: 'ios-folder-outline',
                    2: 'ios-paper-outline',
                    3: 'ios-information-circle',
                },
            }
        },
        methods: {
            renderContent(h, {root, node, data}) {
                // 渲染时根绝角色权限展开节点操作

                if (data.id === 0) {// 顶级目录只显示添加按钮
                    data.disabled = true;

                    return h('span', {
                        style: {
                            display: 'inline-block',
                            width  : '100%'
                        }
                    }, [
                        h('span', [
                            h('Icon', {
                                props: {
                                    type: 'ios-folder-outline'
                                },
                                style: {
                                    marginRight: '8px'
                                }
                            }),
                            h('span', data.title)
                        ]),
                        h('span', {
                            style: {
                                display    : 'inline-block',
                                float      : 'right',
                                marginRight: '32px'
                            }
                        }, [
                            h('Button', {
                                props: Object.assign({}, this.buttonProps, {
                                    icon: 'ios-add',
                                    type: 'primary'
                                }),
                                style: {
                                    width: '64px',
                                    display: this.showOpBtn ? '' : 'none',
                                },
                                on   : {
                                    click: () => { this.append(data) }
                                }
                            })
                        ])
                    ]);
                }

                return h('span', {
                    style: {
                        display   : 'inline-block',
                        width     : '100%',
                        height    : '24px',
                        lineHeight: '24px',
                    },
                    class: 'power_tree_line',
                }, [
                    h('span', [
                        h('Icon', {
                            props: {
                                type: this.treeIconMap[data.level],
                            },
                            style: {
                                marginRight: '8px'
                            }
                        }),
                        h('span', data.title)
                    ]),
                    h('span', {
                        style: {
                            float      : 'right',
                            marginRight: '32px',
                        },
                        class: 'power_tree_op_group',
                    }, [
                        h('Button', {
                            props: Object.assign({}, this.buttonProps, {
                                icon: 'ios-create'
                            }),
                            style: {
                                marginRight: '8px',
                                display: this.showOpBtn ? '' : 'none',
                            },
                            on   : {
                                click: () => { this.edit(root, node, data) }
                            }
                        }),
                        data.level === 3 ? null : h('Button', {
                            props: Object.assign({}, this.buttonProps, {
                                icon: 'ios-add',
                                type: 'primary',
                            }),
                            style: {
                                marginRight: '8px',
                                display: this.showOpBtn ? '' : 'none',
                            },
                            on   : {
                                click: () => { this.append(data) }
                            }
                        }),
                        h('Button', {
                            props: Object.assign({}, this.buttonProps, {
                                icon: 'ios-remove',
                                type: 'error',
                            }),
                            style: {
                                marginRight: '8px',
                                display: this.showOpBtn ? '' : 'none',
                            },
                            on   : {
                                click: () => { this.remove(root, node, data) }
                            }
                        }),
                    ])
                ]);
            },
            append(data) {// 新增
    
                this.editAndCreateModal.propsList = [];

                this.handleEditAndCreateResetForm();

                this.editAndCreateModal.show = true;
                this.editAndCreateModal.title = '新增' + this.editAndCreateModal.levelCreateTitleInfo[data.level];

                this.editAndCreateModal.data.level = data.level + 1;
                this.editAndCreateModal.data.pid = data.id;
                
                if(this.editAndCreateModal.data.level == 1){//如果为目录，则默认设置展开目录
                    this.editAndCreateModal.data.meta_show_always = 1;
                }

                this.handleEditAndCreateSubmit = () => {
    
                    if (!this.handleEditAndCreateModalFormSubmitFieldCheck(Object.assign({}, this.editAndCreateModal.data))) {
                        return false;
                    }
    
                    this.editAndCreateModal.data.props = this.parsePropFormPropList();//解析出props设置

                    rbacUtl.request(
                        {
                            url   : rbacUtl.generalUrlWithUrlPreByUri(rbacUtl.urlList.createPower),
                            method: 'post',
                            data  : this.editAndCreateModal.data
                        },
                        (res) => {
                            data.expand = true;// 展开节点

                            const children = data.children || [];
                            children.push(Object.assign({
                                // title : 'appended node',
                                expand: true
                            }, res.data.data));
                            this.$set(data, 'children', children);

                            this.$Message.success('添加成功');

                            this.handleEditAndCreateResetForm();

                            this.editAndCreateModal.show = false;
                        }
                    );

                };
            },
            remove(root, node, data) {// 删除
                return this.$Modal.confirm({
                    title: '删除确认',
                    content: '确认删除该权限信息吗？',
                    onOk: () => {

                        rbacUtl.request(
                            {
                                url   : rbacUtl.generalUrlWithUrlPreByUri(rbacUtl.urlList.destroyPowerPrefix.replace('{id}',data.id)),
                                method: 'DELETE'
                            },
                            (res) => {

                                if (res.data.code == 0) {
                                    this.$Message.success('删除成功');

                                    const parentKey = root.find(el => el === node).parent;
                                    const parent    = root.find(el => el.nodeKey === parentKey).node;
                                    const index     = parent.children.indexOf(data);
                                    parent.children.splice(index, 1);
                                } else {
                                    this.$Message.error(res.data.message);
                                }


                            }
                        );

                    },
                    onCancel: () => {

                    }
                });


            },
            edit(root, node, data) {// 编辑
                this.editAndCreateModal.show = true;
                this.editAndCreateModal.title = '编辑';

                this.handleEditAndCreateResetForm();
                for (const modalDataKey in this.editAndCreateModal.data) {
                    this.editAndCreateModal.data[modalDataKey] = data[modalDataKey];
                }
    
                //props属性展示列表赋值
                this.editAndCreateModal.propsList = [];
                if (data.props) {
                    for (let indexOfProps in data.props) {
                        this.editAndCreateModal.propsList.push({
                            key  : indexOfProps,
                            value: data.props[indexOfProps],
                        });
                    }
                }

                // 编辑操作
                this.handleEditAndCreateSubmit = () => {
    
                    if (!this.handleEditAndCreateModalFormSubmitFieldCheck(Object.assign({}, this.editAndCreateModal.data))) {
                        return false;
                    }
    
                    this.editAndCreateModal.data.props = this.parsePropFormPropList();//解析出props设置

                    rbacUtl.request(
                        {
                            url   : rbacUtl.generalUrlWithUrlPreByUri(rbacUtl.urlList.updatePowerPrefix.replace('{id}',data.id)),
                            method: 'put',
                            data  : this.editAndCreateModal.data
                        },
                        (res) => {

                            this.$Message.success('修改成功');

                            for (let modalDataKey in data) {
                                if (res.data.data[modalDataKey]) {
                                    data[modalDataKey] = res.data.data[modalDataKey];
                                }
                            }

                            this.handleEditAndCreateResetForm();

                            this.editAndCreateModal.show = false;
                        }
                    );

                };

            },
            getTreeData() {
                rbacUtl.request(
                    {
                        url: rbacUtl.generalUrlWithUrlPreByUri(rbacUtl.urlList.getPowerTree)
                    },
                    (res) => {
                        this.treeData = this.treeDataCheckDeal(res.data.data);
                    }
                );
            },
            handleEditAndCreateSubmit() {},// 在修改和新增提交中重新赋值
            handleEditAndCreateResetForm() {
                // this.$refs[this.editAndCreateModal.formRef].resetFields();
                this.editAndCreateModal.data = Object.assign({},defaultFormData);
            },
            treeDataCheckDeal(routesInfo, parentRoute) {//如果为角色权限查看，展开对应的权限
                for (let routesIndex in routesInfo) {
                    if (this.permissionCheckIdList.includes(routesInfo[routesIndex].id)) {
                        parentRoute && (parentRoute.expand = true);//如果子节点被选中，父亲节点展开
                        routesInfo[routesIndex].checked = true;
                        routesInfo[routesIndex].expand  = true;
                    }
            
                    !routesInfo[routesIndex].meta && (routesInfo[routesIndex].meta = {});
            
                    if (routesInfo[routesIndex].children) {
                        this.treeDataCheckDeal(routesInfo[routesIndex].children, routesInfo[routesIndex])
                    }
                }
        
                return routesInfo;
            },
            handleRolePermissionSubmit() {
                let selectTreeNodeInfoList = this.$refs[this.treeRefName].getCheckedAndIndeterminateNodes(),
                    selectIdList           = selectTreeNodeInfoList.map((selectTreeNodeInfo) => selectTreeNodeInfo.id);
        
                //提交角色修改设置触发
                this.$emit('on-save-role-permission', selectIdList);
            },
            handleEditAndCreateModalFormPropsRemove(index) {//移除prop属性
                this.editAndCreateModal.propsList.splice(index, 1);
            },
            handleEditAndCreateModalFormPropsAdd() {//添加prop属性
                this.editAndCreateModal.propsList.push({
                    key  : '',
                    value: '',
                });
            },
            parsePropFormPropList() {//从propsList中解析出prop属性对象
                let props = {};
                for (let propIndex in this.editAndCreateModal.propsList) {
                    let propInfo = this.editAndCreateModal.propsList[propIndex];
                    if (propInfo.key.replace(new RegExp(/( )/g), '')) {
                        props[propInfo.key] = propInfo.value;
                    }
                }
                return props;
            },
            handleEditAndCreateModalFormSubmitFieldCheck(data) {//表单提交前的字段检测
                var placeReg = new RegExp(/( )/g);
                if (this.editAndCreateModal.data.level !== 3) {
                    if (!this.editAndCreateModal.data.route_name.replace(placeReg, '')) {
                        this.$Message.error('【路由name属性】必须填写');
                        return false;
                    }
            
                    if (!this.editAndCreateModal.data.title.replace(placeReg, '')) {
                        this.$Message.error('【名称】必须填写');
                        return false;
                    }
                }
        
                if (this.editAndCreateModal.data.level === 3) {
                    if (!this.editAndCreateModal.data.title.replace(placeReg, '')) {
                        this.$Message.error('【名称】必须填写');
                        return false;
                    }
                }
        
                return true;
            },
        },
        created() {
            this.getTreeData();
        }
    }
</script>

<style>
    .power_tree_op_group {
        display: none;
    }
    
    .power_tree_line:hover .power_tree_op_group {
        display: inline-block;
    }
    
    .power_tree_line:hover {
        background: #efecec;
    }
</style>
